








                               ******************
                               *** The C-FLEA ***
                               ******************



                  A tiny Virtual Machine implementation for C










                                  Revision 1.0










                         Dunfield Development Services
                         -----------------------------
                             High quality tools for
                              Embedded Development
                                 at low prices.

                      https://dunfield.themindfactory.com


                       Copyright 1990-2005 Dave Dunfield
                              All rights reserved.

            DVM: This is the original documentation for the virtual
                 CPU upon which DVM is based. Notes added 2020



                            C-FLEA Virtual C Machine

                               TABLE OF CONTENTS


                                                                         Page

     1. INTRODUCTION                                                        1

        1.1 The C-FLEA Virtual Machine Interpreter                          1
        1.2 The C-FLEA Development Tool Suite                               2

     2. CAVEATS, NOTES and LIMITATIONS of the C-FLEA                        3


     3. C-FLEA VIRTUAL MACHINE ARCHITECTURE                                 4

        3.1 Registers                                                       4
        3.2 Addressing Modes                                                4
        3.3 Memory addressing instructions                                  5
        3.4 Compare modifier instructions                                   6
        3.5 Jump instructions                                               6
        3.6 Stack manipulation instructions                                 6
        3.7 Misc. Instructions                                              7
        3.8 Unused opcodes                                                  7
    C-FLEA Virtual C Machine                                         Page: 1


    1. INTRODUCTION

          The C-FLEA is a tiny virtual  machine  implementation,  which  has
       been designed  "from the ground  up"  to  run  C  programs.  Programs
       compiled for the C-FLEA use a  "virtual"  instruction set,  which  is
       then executed by a virtual machine interpreter on the target  system.
       This provides many major features, some of which are:

        - The VM can be implemented on processors which would not  otherwise
          be good candidates for a C environment.

        - The VM interpreter can access program and data memory in ways that
          a native processor could not efficiently do.  For example, several
          C-FLEA implementations have been done  which  execute  the  C-FLEA
          code from a serial (I2C bus) memory system.

        - The VM code is very efficient for C, and results in programs which
          are much more compact that most native code implementations.

        - The VM code is portable,  allowing compiled  programs  to  run  on
          completely different hardware platforms  without  re-compiling  or
          otherwise changing the program code.

        - The VM interpreter can control the execution of  the  C-FLEA  code
          much more strictly than can be done with native code.  This  makes
          C-FLEA a good candidate for  a  control  or  "scripting"  language
          embedded within another application.

          This package is licensed for personal use by  the  licencee  only.
       You may not redistribute any of the tools, programs, documentation or
       source code.  DDS authorizes the  redistribution  of  the  C-FLEA  VM
       interpreter and any library functions included in your program by the
       linker in BINARY form only.

          If you wish to redistribute the C-FLEA VM in any application where
       the VM is a feature of your product,  and/or you wish to redistribute
       the development tools, please contact DDS.

       1.1 The C-FLEA Virtual Machine Interpreter

             The C-FLEA virtual machine  interpreter  is  a  small  (usually
          about 1K-bytes)  program which runs on a host CPU,  and implements
          the  C-FLEA  instruction  set.  Due  to  the  simplicity  of   the
          instruction set,  C-FLEA virtual machines can be  implemented  for
          virtually any CPU in a very short time.

             Even the very tiny processors  which  do  not  provide  general
          memory addressing capabilities are good candidates for the C-FLEA,
          because required memory addressing modes can be implemented in the
          VM interpreter.  Even those processors which do not  provide  data
          access to internal memory at all can be used by  implementing  the
          C-FLEA address space via external memory interfaced with  parallel
          ports, or a serial bus such as I2C.
    C-FLEA Virtual C Machine                                         Page: 2


             A very powerful "C-Stamp" processor can be built in the area of
          a large postage stamp,  using a small single-chip CPU,  and a  I2C
          serial EEPROM memory chip.  Due to the instruction set efficiency,
          a 2K EEPROM chip provides for quite a large and  complex  program,
          while an 8K chip gives more capability than  other  small  systems
          having much more memory.  Since EEPROM is non-volatile, and can be
          erased and re-programmed by the CPU,  you can even  download  your
          program  via  a  serial  port...  No  more  "burning"  EPROMS   or
          microcontrollers. Also, since the EEPROM could be accessed as both
          code AND data,  the portion of the EEPROM not used for code can be
          used for long-term non-volatile data storage!

             This package includes several example C-FLEA VM implementations
          which you can use  to  build  your  own  VM,  customized  to  your
          specific processor and system hardware. These examples are located
          in the 'VM' subdirectory. Details of the VM instruction set (which
          you will need to implement your own VM)  are given later  in  this
          document.

       1.2 The C-FLEA Development Tool Suite

             Included in this package is a complete and comprehensive set of
          development tools for the C-FLEA virtual machine,  including  a  C
          compiler, preprocessor,  Optimizer,  Assembler,  Linker,  Library,
          Simulator  (with target debug  interface  capability),  Integrated
          Development Environment and many  other  utilities.  For  complete
          details  of  the  development  tools,  refer  to  the  MICROC.TXT,
          DDSIDE.TXT, ASMCF.TXT and EMCF.TXT files included in this package.

             In addition  to  the  above  tools,  some  of  the  example  VM
          implementations  demonstrate  a  simple  host  interface,  and   a
          resident C-FLEA debugger as part of the VM interpreter.

             The C-FLEA virtual machine is somewhat unusual  to  program  at
          the assembly language level,  however if  you  are  interested  in
          using the ASMCF assembler directly  (or INLINE  assembly  code  in
          your  'C'  programs),  see the ASMCF.TXT file for details on using
          the assembler.  A description of the C-FLEA  VM  architecture  and
          instruction set is given later in this document. You can also look
          at the *.ASM files in  the  LIBCF  subdirectory  for  examples  of
          C-FLEA assembly programming.
    C-FLEA Virtual C Machine                                         Page: 3


    2. CAVEATS, NOTES and LIMITATIONS of the C-FLEA

          The C-FLEA virtual processor has no simple method of dealing  with
       signed 8 bit quantities.  Therefore, 'char' variables and expressions
       are always calculated as positive quantities. The "unsigned" modifier
       only controls how the compiler views that positive value (ie:  'char'
       = signed value in the range of  0-255,  'unsigned  char'  =  unsigned
       value in the range of 0-255).  This affects how the compiler promotes
       other objects involved in an expression. For example:

            int a = -1;   char b = 255;   unsigned char c = 255;

            (a < b) == TRUE     (signed comparison:     -1 < 255    )
            (a < c) == FALSE    (unsigned comparison:   65535 > 255 )

          The C-FLEA virtual machine does not have any method of  performing
       signed division.  Division with signed quantities will  result  in  a
       value equivalent to dividing unsigned quantities with  the  same  bit
       pattern (ie: -32788 to -1 is treated as 32768 to 65535).

          Since the C-FLEA does not have a "carry flag", more work has to be
       done to perform  the  multi-precision  shift/add/subtract  operations
       which are used heavily by the LONGMATH functions.  This causes  these
       functions to be somewhat slower than on most "real"  microprocessors.
       If long math is to be used extensively in a  C-FLEA  project,  it  is
       recommended that you implement the long math functions as  a  virtual
       I/O device,  thereby moving the code to the native cpu (assuming that
       the native CPU is well suited for multi-precision operations).

       DVM:  Most of the C library  (including LONGMATH)  are implemented as
       native code within the virtual machine.
    C-FLEA Virtual C Machine                                         Page: 4


    3. C-FLEA VIRTUAL MACHINE ARCHITECTURE

          This section describes the C-FLEA virtual machine architecture and
       instruction set.

       3.1 Registers

          The C-FLEA virtual machine contains 4 user accessible registers:

            ACC     - 16 bit accumulator 8 bit accesses are auto zero-filled
            INDEX   - 16 bit addressing register, cannot be accessed as 8 bits
            SP      - 8 or 16 bit stack pointer (Depending on RAM size)
            PC      - 16 bit program counter

          ACC always contains 16 valid bits. All operations are performed in
          16 bit precision.  8 bit operands are zero-filled  when  they  are
          fetched.

          SP decrements when data is pushed,  and always points to the  last
          entry which was pushed  (ie:  0,S gives data on  "top"  of stack).
          Systems with 256 bytes or less of RAM may only implement an 8  bit
          SP. In this case, top byte is zeroed by TSA.

          Data is stored in LITTLE ENDIAN format.  Ie:  LOW BYTE  is  FIRST.
          This allows us to use the same address to refer to an 8 bit  or  a
          16 bit quantity.

          There are no user accessible flags.  In the case of CMP,  internal
          flags are maintained only long enough to  accommodate  the  LT-UGE
          instructions.

       3.2 Addressing Modes

          For most general  memory  referencing  instruction,  there  are  8
          memory addressing modes,  which are selected by  the  lower  three
          bits of the instruction opcode.

        Syntax Coding    Description
        ---------------------------------------------------
         #n    x0 ii(ii) Immediate (8 or 16 bit operand)
         aaaa  x1 dd dd  Direct memory address
         I     x2        Indirect (through INDEX register) no offset
         n,I   x3 oo     Indirect (through INDEX register) with 8 bit offset
         n,S   x4 oo     Indirect (through SP) with 8 bit offset
         S+    x5        On Top of Stack (remove)
         [S+]  x6        Indirect through TOS (remove)
         [S]   x7        Indirect through TOS (leave on stack)

        NOTES:
         Mode S+ always pops 16 bits from stack. Only 16 bit values can be
         pushed. Modes [S+] and [S] will always use a 16 bit address on the
         top of the stack, but the final target can be 8 or 16 bits.
    C-FLEA Virtual C Machine                                         Page: 5


       3.3 Memory addressing instructions

          These instructions use the  addressing  modes  listed  above.  The
          actual opcode for the instruction  is  determined  by  adding  the
          addressing mode bits to the opcodes listed below.

        Name  Coding  Description                   (Unused address modes)
        ------------------------------------------------------------------
         LD     00x   Load ACC 16 bits
         LDB    08x   Load ACC 8 bits
         ADD    10x   Add 16 bits
         ADDB   18x   Add 8 bits
         SUB    20x   Subtract 16 bits
         SUBB   28x   Subtract 8 bits
         MUL    30x   Multiply 16 bits
         MULB   38x   Multiply 8 bits
         DIV    40x   Divide 16 bits
         DIVB   48x   Divide 8 bits
         AND    50x   And 16 bits
         ANDB   58x   And 8 bits
         OR     60x   Or 16 bits
         ORB    68x   Or 8 bits
         XOR    70x   Xor 16 bits
         XORB   78x   Xor 8 bits
         CMP    80x   Compare 16 bits (ACC=1 if equal)
         CMPB   88x   Compare 8 bits
         LDI    90x   Load INDEX (16 bits only)
         LEAI   98x   Load INDEX with address           (#n, S+)
         ST     A0x   Store ACC 16 bits                 (#n, S+)
         STB    A8x   Store ACC 8 bits                  (#n, S+)
         STI    B0x   Store INDEX (16 bits only)        (#n, S+)
         SHR    B8x   Shift right (8 bit count only)
         SHL    C0x   Shift left  (8 bit count only)
        NOTES:
          Opcodes 00-C7 always determine operand address.
          Opcodes 00-97 always fetch operand VALUE at that address.

          DVM: TINY (64k) as well as SMALL (up to 128k) addressing modes are
          provided. In SMALL mode, instructions are fetched from one (up to)
          64k block, and data accesses use a second 64k block.
    C-FLEA Virtual C Machine                                         Page: 6


       3.4 Compare modifier instructions

          These instructions follow a CMP instruction, and modify the result
          value  (in  ACC)  to  provide  signed   and   unsigned   magnitude
          comparisons.  These modifier instructions rely on  internal  flags
          which are set by the CMP instruction,  and must IMMEDIATELY follow
          the CMP! Only PUSHA, TAI, JMP, SJMP, JZ, SJZ, JNZ,  SJNZ may occur
          between the CMP and these instructions,  otherwise the  result  of
          the CMP may be lost!

        Name  Coding   Description
        ---------------------------------------------------------------
         LT     C8     ACC = 1 if less than             (signed)
         LE     C9     ACC = 1 if less than or equal    (signed)
         GT     CA     ACC = 1 if greater than          (signed)
         GE     CB     ACC = 1 if greater than of equal (signed)
         ULT    CC     ACC = 1 if lower than            (unsigned)
         ULE    CD     ACC = 1 if lower than or same    (unsigned)
         UGT    CE     ACC = 1 if higher than           (unsigned)
         UGE    CF     ACC = 1 if higher than or same   (unsigned)
        NOTES:
         NOT instruction is used to implement explicit NE.

       3.5 Jump instructions

        Name    Coding    Description
        ---------------------------------------------------------------
         JMP    D0 aa aa  Long jump (16 bit absolute)
         JZ     D1 aa aa  Long jump if ACC=0 (16 bit absolute)
         JNZ    D2 aa aa  Long jump if ACC!=0 (16 bit absolute)
         SJMP   D3 rr     Short jump (8 bit PC offset)
         SJZ    D4 rr     Short jump if ACC=0 (8 bit PC offset)
         SJNZ   D5 rr     Short jump if ACC!=0 (8 bit PC offset)
         IJMP   D6        Indirect jump (Address in ACC)
         SWITCH D7        Jump through switch table (ACC=value, INDEX=table)
         CALL   D8 aa aa  Call subroutine (16 bit absolute address)
         RET    D9        Return from subroutine
        NOTES:
         Switch table format: addr1, value1, addr2, value2, ... 0, defaddr

       3.6 Stack manipulation instructions

        Name    Coding    Description
        ---------------------------------------------------------------
         ALLOC  DA oo     Allocate space on stack (8 bit value)
         FREE   DB oo     Release space on stack (8 bit value)
         PUSHA  DC        Push ACC on stack
         PUSHI  DD        Push INDEX on stack
         TAS    DE        Copy ACC to SP
         TSA    DF        Copy SP to ACC
        NOTES:
         Explicit POP instructions are not required since various address
         modes use (and remove) the top item on the stack (POPA = LD S+).
    C-FLEA Virtual C Machine                                         Page: 7


       3.7 Misc. Instructions

        Name    Coding    Description
        ---------------------------------------------------------------
         CLR    E0        Zero ACC
         COM    E1        Complement ACC (ACC = ACC XOR FFFF)
         NEG    E2        Negate ACC (ACC = 0 - ACC)
         NOT    E3        ACC = 1 if ACC was 0, else ACC = 0
         INC    E4        Increment ACC
         DEC    E5        Decrement ACC
         TAI    E6        Copy ACC to INDEX
         TIA    E7        Copy INDEX to ACC
         ADAI   E8        Add ACC to INDEX
         ALT    E9        Get alternate result from MUL/DIV
         OUT    EA pp     Output byte in ACC to PORT    DVM: does not implement
         IN     EB pp     Read byte from PORT           DVM:    IN or OUT
         NATIVE EC        Switch to NATIVE execution    DVM: does not implement
    DVM: LIB    FF xx     Accesses internal library functions
        NOTES:
         ALT obtains the remainder after DIV, and in some implementations,
         also obtains the high word after a multiply. This instruction must
         be executed IMMEDIATELY after the MUL or DIV. A PUSHA or TAI inst.
         is allowed between the MUL/DIV (In case you want to save both results),
         but any other instruction may cause the alternate result to be lost!

         NATIVE execution is not available in all implementations. Some
         versions use opcode EC as a SYS instruction, which accepts a single
         byte operand, and performs some system specific functions.

       3.8 Unused opcodes

             ED-FF Available for future expansion. DVM: FF is used


       This instruction set and associated mnemonics are:

       Copyright 1994-2020 Dave Dunfield
       All rights reserved.
